/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.udt.designtime.manager.udtdtconsistencychecklistener;

import com.inspur.edp.bef.bizentity.bizentitydtevent.BizEntityFieldDTEventListener;
import com.inspur.edp.bef.bizentity.dtconsistencycheck.fieldeventargs.AbstractBeFieldEventArgs;
import com.inspur.edp.bef.bizentity.dtconsistencycheck.fieldeventargs.ChangingFieldDataTypeEventArgs;
import com.inspur.edp.bef.bizentity.dtconsistencycheck.fieldeventargs.ChangingFieldLabelIdEventArgs;
import com.inspur.edp.bef.bizentity.dtconsistencycheck.fieldeventargs.ChangingFieldObjectTypeEventArgs;
import com.inspur.edp.bef.bizentity.dtconsistencycheck.fieldeventargs.RemovingFieldEventArgs;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.collection.GspFieldCollection;
import com.inspur.edp.cef.designtime.api.dtconsistencycheck.ConsistencyCheckEventMessage;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.element.ElementCollection;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.util.List;

public class UdtFieldDtConsistencyCheckListener extends BizEntityFieldDTEventListener {
  /**
   * 删除节点监听事件
   *
   * @param args
   * @return
   */
  @Override
  public RemovingFieldEventArgs removingField(RemovingFieldEventArgs args) {
    return (RemovingFieldEventArgs)fieldConsistencyCheck(args);
  }
  /**
   * 进行依赖性检查
   *
   * @param args
   * @return
   */
  private AbstractBeFieldEventArgs fieldConsistencyCheck(AbstractBeFieldEventArgs args){
    String returnMessage = getDependencyInfos(args.getMetadataPath(), args.getBeId(),args.getFieldId());
    if (returnMessage == null || returnMessage.length() == 0) {
      return args;
    }
    ConsistencyCheckEventMessage message = new ConsistencyCheckEventMessage(false, returnMessage);
    args.addEventMessage(message);
    return args;
  }
  /**
   * 获取的关联信息
   *
   * @param metadataPath 元数据路径
   * @param beId         元数据ID
   * @return 关联当前BE的关联信息
   */
  protected String getDependencyInfos(String metadataPath, String beId, String fieldId) {
    MetadataService metadataService = SpringBeanUtils
        .getBean(com.inspur.edp.lcm.metadata.api.service.MetadataService.class);
    List<GspMetadata> gspMetadataList = metadataService
        .getMetadataListByRefedMetadataId(metadataPath, beId);
    StringBuilder strBuilder = new StringBuilder();
    gspMetadataList.forEach(gspMetadata -> {
      if (!gspMetadata.getHeader().getType().equals("UnifiedDataType")) {
        return;
      }
      UnifiedDataTypeDef unifiedDataType = (UnifiedDataTypeDef) metadataService
          .loadMetadata(gspMetadata.getHeader().getFileName(), gspMetadata.getRelativePath())
          .getContent();
      if(!getSingleUdtDependence(unifiedDataType,fieldId) && !getMultiUdtDependence(unifiedDataType,fieldId))
        return;
      String packageName = projectName(gspMetadata.getRelativePath());
      strBuilder.append("工程【").append(packageName)
          .append("】中UDT【").append(unifiedDataType.getCode()).append("】依赖了当前字段。\n");
    });
    if (strBuilder.toString() == null || strBuilder.toString().length() == 0) {
      return null;
    }
    return strBuilder.toString();
  }
  /**
   * 获取工程
   *
   * @param metadataPath 元数据路径
   * @return 元数据包名
   */
  protected String projectName(String metadataPath) {
    MetadataProjectService projectService = SpringBeanUtils
        .getBean(com.inspur.edp.lcm.metadata.api.service.MetadataProjectService.class);
    return projectService.getMetadataProjInfo(metadataPath).getName();
  }
  protected boolean getSingleUdtDependence(UnifiedDataTypeDef udtElement, String fieldId){
    if(udtElement instanceof SimpleDataTypeDef){
      GspAssociationCollection gspAssociations = ((SimpleDataTypeDef) udtElement).getChildAssociations();
      if(gspAssociations.size() == 0){
        return false;
      }
      GspFieldCollection refElements = gspAssociations.get(0).getRefElementCollection();
      if(refElements.size() == 0){
        return false;
      }
      for(IGspCommonField refElement : refElements){
        if(refElement.getRefElementId().equals(fieldId))
          return true;
      }
    }
    return false;
  }

  protected boolean getMultiUdtDependence(UnifiedDataTypeDef udtElement, String fieldId) {
    if (!(udtElement instanceof ComplexDataTypeDef))
      return false;
    ElementCollection fields = ((ComplexDataTypeDef) udtElement).getElements();
    if (fields.size() == 0)
      return false;
    for (IGspCommonField field : fields) {
      //遍历多值UDT的每个字段
      if (field.getChildAssociations().size() == 0)
        continue;
      GspFieldCollection refElements = field.getChildAssociations().get(0)
          .getRefElementCollection();
      if (refElements.size() == 0) {
        return false;
      }
      for (IGspCommonField refElement : refElements) {
        if (refElement.getRefElementId().equals(fieldId))
          return true;
      }
    }
    return false;
  }
}
